{% extends "swarming/base.html" %}


{% block headers %}
<style>
  h1 {
    margin-top: 10px;
    margin-bottom: 10px;
  }

  h2 {
    margin-top: 10px;
    margin-bottom: 5px;
  }

  h2.inline {
    display: inline;
  }

  table.property_table {
    font-family: monospace;
    border-spacing: 0;
  }

  table.property_table tbody tr:nth-child(even) {
    background-color: #eeeeee;
  }

  table.property_table td {
    padding-left: 0.5em;
    padding-right: 0.5em;
  }

  table.property_table tbody tr:hover {
    background-color: #eeffee;
  }

  table.property_table tbody tr td:first-child {
    white-space: nowrap;
  }

  .failed_test {
    background-color: #ffdddd;
  }

  .blink {
    animation: blink 1s steps(5, start) infinite;
    -webkit-animation: blink 1s steps(5, start) infinite;
  }
  @keyframes blink {
    to { visibility: hidden; }
  }
  @-webkit-keyframes blink {
    to { visibility: hidden; }
  }

  .help_text {
    background-color: #ffffee;
  }

  .spaced {
    margin-top: 10px;
    margin-bottom: 5px;
  }
</style>
{% endblock %}


{% block body %}
{% import 'swarming/bot_view.html' as bot_view %}

<h1>Task summary</h1>
<a href="/user/tasks">Back to tasks list</a>
<p>

<div title="Information about the request itself that doesn't include what is being run; it's about the context and description.">
  <h2>Request metadata</h2>
  <table class="property_table">
    <tbody>
      <tr title="Name of the task, used for display purpose only.">
        <td>Name</td>
        <td>{{request.name}}</td>
      </tr>
      <tr title="Who triggered this task, as reported by the client.">
        <td>User</td>
        <td>
          {% if request.user %}
            {{request.user}}
          {% else %}
            &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
      <tr title="Authenticated credential used by the client to trigger this task.">
        <td>Authenticated</td>
        <td>
          {# The only reason for this condition is to not crash on older
          entities. #}
          {% if request.authenticated %}
            {{request.authenticated.to_bytes()}}
          {% else %}
            &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
      <tr title="Task priority is between 1 and 255, lower value is higher priority. Higher priority requests are executed first.">
        <td>Priority</td>
        <td>{{request.priority}}</td>
      </tr>
      <tr title="When the request was done by the client.">
        <td>Created</td>
        <td>{{request.created_ts|datetimeformat}}</td>
      </tr>
      <tr title="When this request becomes so old it's not even worth handing to a bot. It may happen to low priority on a busy fleet.">
        <td>Expiration</td>
        <td>
          {{request.expiration_ts|datetimeformat}}
          ({{(request.expiration_ts-request.created_ts)|timedeltaformat}})
        </td>
      </tr>
      <tr title="Tags used for searching and/or analyzing groups of tasks.">
        <td>Tags</td>
        <td>{{request.tags|join('<br>'|safe)}}</td>
      </tr>
      <tr title="Parent task that created this task.">
        <td>Parent task</td>
        <td>
          {% if parent_task %}
            <a href="/user/task/{{parent_task.key_packed}}">{{parent_task.name}}</a>
          {% else %}
            &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
    </tbody>
  </table>
</div>

<div title="Information about what was asked to be run. This is what is used for task deduplication.">
  <div class="spaced">
    <h2 class="inline">Request properties</h2>
    {% if is_privileged_user %}
      <form method="POST" action="/user/task/{{task.key_packed}}/retry" style="display:inline">
        <input type="submit" value="Retry" style="display:inline"></input>
        <input type="hidden" name="xsrf_token" value="{{xsrf_token}}" />
      </form>
    {% endif %}
  </div>
  <table class="property_table">
    <tbody>
      <tr title="The request dimensions is the minimum set of properties a bot must advertise to be able to execute this task.">
        <td>Request dims</td>
        <td>{{bot_view.render_dict(request.properties.dimensions)}}</td>
      </tr>
      <tr title="The maximum number of seconds that the command may use, otherwise it is forcibly killed.">
        <td>Exec timeout</td>
        <td>{{request.properties.execution_timeout_secs}}</td>
      </tr>
      <tr title="The maximum number of seconds that the command may not output any stdout in a single shot.">
        <td>I/O timeout</td>
        <td>{{request.properties.io_timeout_secs}}</td>
      </tr>
      <tr title="Additional environment variables to the one provided by the bot.">
        <td>Env vars</td>
        <td>{{bot_view.render_dict(request.properties.env)}}</td>
      </tr>
      <tr title="If True, successful task results may be reused for subsequent requests, so the task can be deduped.">
        <td>Idempotent</td>
        <td>{{request.properties.idempotent}}</td>
      </tr>
      <tr title="Actual command executed by the bot.">
        <td>Commands</td>
        <td>
          {% for cmd in request.properties.commands %}
          {{cmd|join(' ')}}<br>
          {% endfor %}
        </td>
      </tr>
    </tbody>
  </table>
</div>

<div title="Information about the result: the task was run where (which bot), when and what is the result.">
  <h2>Execution</h2>
  <table class="property_table">
    <tbody>
      <tr title="The previous task executed by this bot before this task, if any.">
        <td>Previous task</td>
        <td>
          {% if previous_task %}
          <a href="/user/task/{{previous_task.key_packed}}">
            &#x2190; {{previous_task.name}}
          </a>
          {% else %}
          &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
      <tr title="The next task executed by this bot, if any.">
        <td>Following task</td>
        <td>
          {% if following_task %}
          <a href="/user/task/{{following_task.key_packed}}">
            {{following_task.name}} &#x2192;
          </a>
          {% else %}
          &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
      <tr title="When the bot was handed this task.">
        <td>Started</td>
        <td>{{task.started_ts|datetimeformat}}</td>
      </tr>
      <tr title="Last time this bot sent an update about this task.">
        <td>Last updated</td>
        <td>{{(now-task.modified_ts)|timedeltaformat}} ago</td>
      </tr>
      <tr title="Time between when the request was done and the bot started the task.">
        <td>Pending time</td>
        <td>
          {{bot_view.pending_star(task)}}{{task.pending_now(now)|timedeltaformat}}
        </td>
      </tr>
      <tr title="When the task was completed, if done.">
        <td>Completed</td>
        <td>{{task.completed_ts|datetimeformat}}</td>
      </tr>
      <tr title="Duration of the task, up to now if the task is still on-going.">
        <td>Duration</td>
        <td>
          {{bot_view.running_star(task)}}{{task.duration_now(now)|timedeltaformat}}
        </td>
      </tr>
      <tr title="Moment where the task was declared a failure by the server due to internal error or expiration.">
        <td>Abandoned</td>
        <td>
          {{task.abandoned_ts|datetimeformat}}
          {% if task.abandoned_ts %}
            {% if task.started_ts %}
              ({{(task.abandoned_ts-task.started_ts)|timedeltaformat}} since task
              started)
            {% else %}
              ({{(task.abandoned_ts-request.created_ts)|timedeltaformat}} since
              task request)
            {% endif %}
          {% endif %}
        </td>
      </tr>
      <tr title="Current state of the task, may be pending, running, completed, bot_died, expired, canceled.">
        <td>State</td>
        <td>
          {{task.to_string()}} ({{task.state}})
          {% if task.can_be_canceled and is_admin %}
            <form id="cancel" method="post" action="/user/tasks/cancel">
              <input type="hidden" name="xsrf_token" value="{{xsrf_token}}" />
              <input type="hidden" name="task_id" value="{{task.key_packed}}" />
              <input type="submit" value="Cancel" />
            </form>
          {% endif %}
        </td>
      </tr>
      <tr title="Link to the bot that executed this task, if any.">
        <td>Bot</td>
        <td>{{bot_view.bot_link(task.bot_id, is_privileged_user)}}</td>
      </tr>
      <tr title="Current bot dimensions. TODO(maruel): List dimensions at time of task reaping.">
        <td>Bot dimensions</td>
        <td>{{bot_view.bot_dimensions(bot)}}</td>
      </tr>
      <tr title="Current bot version. TODO(maruel): List bot version at time of task reaping.">
        <td>Bot version</td>
        <td>{{task.bot_version}}</td>
      </tr>
      <tr title="List of server versions that touched this task.">
        <td>Server version</td>
        <td>
          {% for v in task.server_versions %}
            {% if is_gae_admin %}
              <a href="https://appengine.google.com/logs?&app_id={{full_appid}}&version_id={{v}}">
                {{v}}
              </a>
            {% else %}
              {{v}}
            {% endif %}
          {% endfor %}
        </td>
      </tr>
      <tr class="{% if task.failure %}failed_test{% endif%}" title="True if the task failed normally.">
        <td>Failure</td>
        <td>{{task.failure}}</td>
      </tr>
      <tr class="{% if task.internal_failure %}failed_test{% endif%}" title="True if an internal Swarming error occured for this task. A BSOD is considered an internal failure.">
        <td>Internal failure</td>
        <td>{{task.internal_failure}}</td>
      </tr>
      <tr title="Process exit code for each commands executed on the bot.">
        <td>Exit codes</td>
        <td>{{task.exit_codes}}</td>
      </tr>
      <tr title="Children tasks that were created by this task.">
        <td>Children tasks</td>
        <td>
          {% if children_tasks %}
            {% for children in children_tasks %}
              <a href="/user/task/{{children.key_packed}}">{{children.name}}</a>
              <br>
            {% endfor %}
          {% else %}
            &#8209;&#8209;
          {% endif %}
        </td>
      </tr>
      <tr title="Cost of running this task, as reported by the bot, if
      applicable.">
        {% if task.cost_saved_usd %}
          <td>$ USD saved</td>
          <td>
            <span style="color:green">{{task.cost_saved_usd|round(4) }} $</span>
          </td>
        {% else %}
          <td>$ USD</td>
          <td>
            {% if task.cost_usd %}
              {{task.cost_usd|round(5) }} $
            {% else %}
              &#8209;&#8209;
            {% endif %}
          </td>
        {% endif %}
      </tr>
      <tr title="A task may be tried 2 times. This list the try number starting at 1.">
        <td>Try number</td>
        <td>{{task.try_number}}</td>
      </tr>
      {% if task.deduped_from %}
        <tr title="This task was not executed, results from the task listed here were reused as-is.">
          <td><strong>Was deduped from</strong></td>
          <td>
            <a href="/user/task/{{task.deduped_from}}">{{task.deduped_from}}</a>
          </td>
        </tr>
      {% endif %}
    </tbody>
  </table>
</div>

<br>
<div class=help_text>
<h2>Help</h2>
<span style="margin-bottom:0">To run this task locally, execute:</span>
<pre style="margin-top:0">  python swarming.py reproduce -S {{host_url}} {{task.key_packed}}</pre>
<span style="margin-bottom:0">Download task output results from ISOLATED_OUTDIR into directory "foo":</span>
<pre style="margin-top:0">  python swarming.py collect -S {{host_url}} --task-output-dir=foo {{task.key_packed}}</pre>
<span style="margin-bottom:0">Looking for swarming.py?</span>
<pre style="margin-top:0">  git clone https://code.google.com/p/swarming.client.git</pre>
</div>

<h3>Outputs:</h3>
<pre>
{% for out in task.get_outputs() %}Output:
{{out.decode('utf-8', 'replace')}}{% endfor %}{% if is_running %}<p class="console"><span class="blink">|</span>{% endif %}
</pre>

{% endblock %}
